package com.tools.handler.analysis;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.tools.common.result.Result;
import com.tools.handler.StepHandler;
import com.tools.pojo.test.AnalysisResult;
import com.tools.pojo.test.AnalysisRule;
import com.tools.pojo.test.RuleMatchResult;
import com.tools.pojo.workflow.bo.StepContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class DataAnalysisStepHandler implements StepHandler {

    private static final String STEP_CODE = "DATA_ANALYSIS";

    @Override
    public String getStepCode() {
        return STEP_CODE;
    }

    @Override
    public Result<?> execute(StepContext context) {
        long startTime = System.currentTimeMillis();

        try {
            log.info("开始执行数据分析步骤，流程实例ID: {}", context.getFlowInstanceId());

            // 获取数据列表
            List<Map<String, Object>> dataList = context.getContextData("dataList", List.class);
            
            // 获取规则列表并进行类型转换
            List<?> rawRules = context.getContextData("analysisRules", List.class);
            List<AnalysisRule> rules = convertToAnalysisRules(rawRules);
            
            if (dataList == null || rules == null || rules.isEmpty()) {
                return Result.fail("数据或规则配置缺失");
            }

            // 执行数据分析
            AnalysisResult analysisResult = analyzeData(dataList, rules);
            analysisResult.setProcessingTime(System.currentTimeMillis() - startTime);
            analysisResult.setTotalRecords(dataList.size());

            // 计算匹配的记录数
            int matchedRecords = calculateMatchedRecords(dataList, rules);
            analysisResult.setMatchedRecords(matchedRecords);

            // 生成分析摘要
            Map<String, Object> summary = generateSummary(analysisResult);
            analysisResult.setSummary(summary);

            // 将分析结果存入上下文
            context.putContextData("analysisResult", analysisResult);

            log.info("数据分析步骤执行成功，处理 {} 条记录，匹配 {} 条规则",
                    dataList.size(), analysisResult.getMatchedRules());

            return Result.success("数据分析完成", analysisResult);

        } catch (Exception e) {
            log.error("数据分析步骤执行失败", e);
            return Result.fail("数据分析失败: " + e.getMessage());
        }
    }

    private AnalysisResult analyzeData(List<Map<String, Object>> dataList, List<AnalysisRule> rules) {
        AnalysisResult result = new AnalysisResult();
        result.setSuccess(true);
        result.setMessage("数据分析完成");

        // 对每条规则进行匹配分析
        for (AnalysisRule rule : rules) {
            RuleMatchResult matchResult = applyRuleToData(dataList, rule);
            result.addMatchResult(matchResult);
        }

        return result;
    }

    private List<AnalysisRule> convertToAnalysisRules(List<?> rawRules) {
        if (rawRules == null) {
            return null;
        }
        
        // 使用JavaTimeModule处理Java 8日期时间类型
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        
        return rawRules.stream()
                .map(item -> {
                    if (item instanceof AnalysisRule) {
                        return (AnalysisRule) item;
                    } else if (item instanceof Map) {
                        try {
                            // 将LinkedHashMap转换为AnalysisRule对象
                            return objectMapper.convertValue(item, AnalysisRule.class);
                        } catch (Exception e) {
                            log.error("转换规则对象失败: {}", e.getMessage(), e);
                            return null;
                        }
                    }
                    return null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
    
    private RuleMatchResult applyRuleToData(List<Map<String, Object>> dataList, AnalysisRule rule) {
        RuleMatchResult result = new RuleMatchResult();
        result.setRuleId(rule.getId());
        result.setRuleName(rule.getRuleName());
        result.setField(rule.getField());
        result.setOperation(rule.getOperation());
        result.setExpectedValue(rule.getValue());
        result.setDescription(rule.getDescription());

        // 构建匹配表达式
        String matchExpression = String.format("%s %s %s",
                rule.getField(), rule.getOperation(), rule.getValue());
        result.setMatchExpression(matchExpression);

        // 检查是否有数据匹配该规则
        boolean anyMatch = dataList.stream().anyMatch(record -> {
            Object fieldValue = record.get(rule.getField());
            return evaluateRule(fieldValue, rule);
        });

        result.setMatched(anyMatch);

        // 设置实际值（取第一条记录的值作为示例）
        if (!dataList.isEmpty()) {
            result.setActualValue(dataList.get(0).get(rule.getField()));
        }

        return result;
    }

    private boolean evaluateRule(Object fieldValue, AnalysisRule rule) {
        if (fieldValue == null) {
            return false;
        }

        String operation = rule.getOperation();
        String expectedValue = rule.getValue();

        try {
            return switch (operation) {
                case ">" -> compareNumbers(fieldValue, expectedValue) > 0;
                case ">=" -> compareNumbers(fieldValue, expectedValue) >= 0;
                case "<" -> compareNumbers(fieldValue, expectedValue) < 0;
                case "<=" -> compareNumbers(fieldValue, expectedValue) <= 0;
                case "=", "==" -> equals(fieldValue, expectedValue);
                case "!=" -> !equals(fieldValue, expectedValue);
                case "like" -> like(fieldValue, expectedValue);
                case "in" -> in(fieldValue, expectedValue);
                case "not in" -> !in(fieldValue, expectedValue);
                default -> {
                    log.warn("未知的操作符: {}", operation);
                    yield false;
                }
            };
        } catch (Exception e) {
            log.warn("规则评估失败: {} {} {}, 错误: {}",
                    rule.getField(), operation, expectedValue, e.getMessage());
            return false;
        }
    }

    private int compareNumbers(Object fieldValue, String expectedValue) {
        double fieldNum = Double.parseDouble(fieldValue.toString());
        double expectedNum = Double.parseDouble(expectedValue);
        return Double.compare(fieldNum, expectedNum);
    }

    private boolean equals(Object fieldValue, String expectedValue) {
        return fieldValue.toString().equals(expectedValue);
    }

    private boolean like(Object fieldValue, String expectedValue) {
        String fieldStr = fieldValue.toString();
        // 简单的like匹配，支持 % 通配符
        if (expectedValue.contains("%")) {
            String regex = expectedValue.replace("%", ".*");
            return fieldStr.matches(regex);
        } else {
            return fieldStr.contains(expectedValue);
        }
    }

    private boolean in(Object fieldValue, String expectedValue) {
        String fieldStr = fieldValue.toString();
        // 支持逗号分隔的值列表
        String[] values = expectedValue.split(",");
        return Arrays.stream(values)
                .map(String::trim)
                .anyMatch(value -> value.equals(fieldStr));
    }

    private int calculateMatchedRecords(List<Map<String, Object>> dataList, List<AnalysisRule> rules) {
        return (int) dataList.stream()
                .filter(record -> rules.stream().anyMatch(rule -> evaluateRule(record.get(rule.getField()), rule)))
                .count();
    }

    private Map<String, Object> generateSummary(AnalysisResult analysisResult) {
        Map<String, Object> summary = new HashMap<>();
        summary.put("totalRules", analysisResult.getTotalRules());
        summary.put("matchedRules", analysisResult.getMatchedRules());
        summary.put("matchRate", String.format("%.2f%%",
                (double) analysisResult.getMatchedRules() / analysisResult.getTotalRules() * 100));
        summary.put("processingTime", analysisResult.getProcessingTime() + "ms");

        // 按字段统计匹配情况
        Map<String, Long> fieldMatchCount = analysisResult.getMatchResults().stream()
                .filter(RuleMatchResult::isMatched)
                .collect(Collectors.groupingBy(RuleMatchResult::getField, Collectors.counting()));
        summary.put("fieldMatchStats", fieldMatchCount);

        return summary;
    }

}
